home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume89
/
workbnch
/
launch.1
< prev
next >
Wrap
Text File
|
1989-01-31
|
11KB
|
458 lines
Path: xanth!ames!mailrus!ulowell!page
From: page@swan.ulowell.edu (Bob Page)
Newsgroups: comp.sources.amiga
Subject: v89i002: launch - start workbench tasks from cli
Message-ID: <11476@swan.ulowell.edu>
Date: 31 Jan 89 05:00:17 GMT
Sender: news@swan.ulowell.edu
Organization: University of Lowell, Computer Science Dept.
Lines: 446
Approved: page@swan.ulowell.edu
Submitted-by: peter@sugar.uu.net (Peter da Silva)
Posting-number: Volume 89, Issue 2
Archive-name: workbench/launch.1
This is an example of how you run a workbench application. As you can
see, it's pretty complex... even with the stuff encapsulated like
this. However, once you get it working it works just fine... unlike
the CLI. Just ask anyone who's tried to run a program under the CLI
from, say, runback.
[Originally posted Sept. 88 in alt.sources.amiga. ..Bob]
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# Makefile
# launch.c
# launch.doc
# util.c
# wbcleanup.c
# wbfree.c
# wblaunch.c
# This archive created: Mon Jan 30 15:27:38 1989
cat << \SHAR_EOF > Makefile
TEXT= launch.doc launch.c wblaunch.c wbfree.c wbcleanup.c util.c Makefile
BIN= launch wbcleanup
LOBJS= launch.o wblaunch.o wbfree.o util.o
WOBJS= wbcleanup.o wbfree.o
.SUFFIXES: .c .o .h .x
.c.o:
-delete $*.o
cc +P -B -DAMIGA $*.c
all: $(BIN)
launch: $(LOBJS)
-delete launch
ln -o launch $(LOBJS) -lcl32
wbcleanup: $(WOBJS)
-delete wbcleanup
ln -o wbcleanup $(WOBJS) -lcl32
launch.arc: $(TEXT) $(BIN)
arc a launch $(TEXT) $(BIN)
launch.shar: $(TEXT)
shar >launch.shar $(TEXT)
clean:
-delete #?.o #?.bak #?.arc #?.shar launch wbcleanup
SHAR_EOF
cat << \SHAR_EOF > launch.c
#include <libraries/dosextens.h>
#include <exec/ports.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <stdio.h>
struct MsgPort *FindPort(), *CreatePort();
struct WBStartup *Launch(), *GetMsg();
struct Process *FindTask();
main(ac, av)
int ac;
char **av;
{
struct MsgPort *rport;
struct Process *me;
struct CommandLineInterface *cli;
struct WBStartup *startup;
long stack;
int pri;
char *win;
int wait;
int got_arg;
stack = 0;
pri = 0;
win = 0;
wait = 0;
if(ac < 2 || strcmp(av[1], "?") == 0) {
fprintf(stderr,
"launch [stack nnnn] [window name] [priority PRI] [wait] program [arguments]\n"
);
exit((ac<2)?5:0);
}
got_arg = 1;
while(got_arg == 1 && ac >= 3) {
got_arg = 0;
if(dictcmp(av[1], "window") == 0) {
win = av[2];
av += 2;
ac -= 2;
got_arg = 1;
} else if(dictcmp(av[1], "stack") == 0) {
stack = atol(av[2]);
av += 2;
ac -= 2;
got_arg = 1;
} else if(dictcmp(av[1], "priority") == 0) {
pri = atoi(av[2]);
av += 2;
ac -= 2;
got_arg = 1;
} else if(dictcmp(av[1], "wait") == 0) {
wait = 1;
av ++;
ac --;
got_arg = 1;
}
}
if(wait == 0) {
if(!(rport = FindPort("Workbench.Cleanup"))) {
fprintf(stderr, "Could not find Workbench.Cleanup port.\n");
fprintf(stderr, "Are you sure you ran wbcleanup?\n");
exit(20);
}
} else {
if(!(rport = CreatePort(0, 0))) {
printf("Can't create reply port.\n");
exit(20);
}
}
if(stack == 0) {
me = FindTask(0);
if(me->pr_CLI) {
cli = (struct CommandLineInterface *)(me->pr_CLI<<2);
stack = cli->cli_DefaultStack<<2; /* DefaultStack is in Longwords */
} else
stack = me->pr_StackSize;
}
if(!Launch(rport, av[1], &av[1], ac-1, pri, win, stack)) {
fprintf(stderr, "Could not launch %s error %d\n", av[1], IoErr());
exit(20);
}
if(wait != 0) {
WaitPort(rport);
startup = GetMsg(rport);
FreeStartup(startup);
DeletePort(rport);
}
exit(0);
}
SHAR_EOF
cat << \SHAR_EOF > launch.doc
LAUNCH -- start a workbench application from the CLI.
This is an example of how you run a workbench application. As you can see,
it's pretty complex... even with the stuff encapsulated like this. However,
once you get it working it works just fine... unlike the CLI. Just ask anyone
who's tried to run a program under the CLI from, say, runback.
Usage:
run wbcleanup (only once, in your CLI)
launch [options] program [filename]...
Loads and executes program in a workbench environment, then returns to
the CLI.
Options:
stack nnnn
Specifies initial stack for the program.
priority pppp
Specifies initial priority for the program.
window wwww
Specifies TOOLWINDOW for the program.
wait
Wait for reply, rather than passing it off to wbcleanup.
wblaunch.c:
message = Launch(port, program, argv, argc, pri, win, stack);
Launch loads and executes program in a workbench environment. The
specified port is where the startup message will be returned. The
arguments will be passed to the program, workbench-style (directory
lock and filename). The first argument should be the same as the
program, but it's possible to spawn a program in an illicit way. If
you don't want to specify a window, use NULL. You need to specify a
stack.
If you don't want to specify a port, run wbcleanup and use the public
message port "Workbench.Cleanup".
You really don't need to do anything with the message when it's
returned from Launch, but it's a convenient non-zero value to indicate
success.
wbfree.c:
FreeStartup(message);
FreeStartup takes a startup message created by Launch and releases all
the public memory, removes the lock, and so on. It should be called
after the startup message is returned.
launch.c:
This contains the mainline for the 'launch' program. Most of it is
arg parsing.
wbcleanup.c:
This contains the mainline for the 'wbcleanup' program.
util.c:
dictcmp(s1, s2);
An analog to strcmp, but ignores case differences in words. Not a full
dictionary comparison, since it doesn't sort numbers by their spelling.
SHAR_EOF
cat << \SHAR_EOF > util.c
#include <ctype.h>
dictcmp(s1, s2)
char *s1;
char *s2;
{
while(*s1 && *s2) {
char c1 = *s1;
char c2 = *s2;
if(isupper(c1)) c1 = tolower(c1);
if(isupper(c2)) c2 = tolower(c2);
if(c1 != c2)
return c1-c2;
s1++;
s2++;
}
return *s1 - *s2;
}
SHAR_EOF
cat << \SHAR_EOF > wbcleanup.c
#include <exec/memory.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
struct MsgPort *rport, *CreatePort();
struct WBStartup *startup, *GetMsg();
main()
{
if(!(rport = CreatePort("Workbench.Cleanup", 0))) {
printf("Can't create Workbench.Cleanup port.\n");
exit(20);
}
while(1) {
WaitPort(rport);
startup = GetMsg(rport);
FreeStartup(startup);
}
}
SHAR_EOF
cat << \SHAR_EOF > wbfree.c
#include <exec/memory.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
FreeStartup(msg)
struct WBStartup *msg;
{
/* Free the files. Assumes they have been allocated via Launch, so
* they're just AllocMemmed. UnLock all the Locks, and Free the
* names.
*/
if(msg->sm_ArgList) {
int i;
for(i = 0; i < msg->sm_NumArgs; i++) {
if(msg->sm_ArgList[i].wa_Lock)
UnLock(msg->sm_ArgList[i].wa_Lock);
if(msg->sm_ArgList[i].wa_Name)
FreeMem(msg->sm_ArgList[i].wa_Name,
strlen(msg->sm_ArgList[i].wa_Name)+1);
}
FreeMem(msg->sm_ArgList,
sizeof(struct WBArg) * msg->sm_NumArgs);
}
/* Here goes the program...
*/
if(msg->sm_Segment)
UnLoadSeg(msg->sm_Segment);
/* And the name of the window. Again, assuming it's allocated by
* Launch, so it just fits in its AllocMemmed buffer.
*/
if(msg->sm_ToolWindow)
FreeMem(msg->sm_ToolWindow,
strlen(msg->sm_ToolWindow)+1);
/* And finally the message itself */
FreeMem(msg, sizeof(struct WBStartup));
}
SHAR_EOF
cat << \SHAR_EOF > wblaunch.c
#include <exec/memory.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
UBYTE *AllocMem();
BPTR LoadSeg();
struct MsgPort *CreateProc();
/* Launch(rport, name, argv, argc, pri, win, stack) -- launch a program.
*
* Launch builds a startup message, loads a program, and launches it.
*
* Arguments:
* rport -- reply port to receive startup message back when the program
* finishes.
* name -- File name for the program to load.
* argv -- list of filenames to pass to loaded program.
* argc -- length of argument list.
* pri -- priority of the new process.
* win -- ToolWindow for the new process, or NULL.
* stack -- Stack size for the new process.
*
* argv[0] should be the same as the program. pri should normally be 0.
* stack should normally be at least 4K.
*/
struct WBStartup *
Launch(rport, name, argv, argc, pri, win, stack)
struct MsgPort *rport;
char *name;
char **argv;
int argc;
long pri;
char *win;
ULONG stack;
{
ULONG flock;
struct WBStartup *msg;
char *s, *namep;
int i;
if(!rport)
return 0;
/* Get some space to work in -- the startup message */
msg = (struct WBStartup *)
AllocMem(sizeof(struct WBStartup), MEMF_PUBLIC|MEMF_CLEAR);
if(!msg)
return 0;
/* Now load the program */
msg->sm_Segment = LoadSeg(name);
if(!msg->sm_Segment) {
FreeStartup(msg);
return 0;
}
/* Allocate and link in the window description */
if(win) {
msg->sm_ToolWindow = (char *)AllocMem(strlen(win)+1, MEMF_PUBLIC);
if(!msg->sm_ToolWindow) {
FreeStartup(msg);
return 0;
}
strcpy(msg->sm_ToolWindow, win);
} else
msg->sm_ToolWindow = 0;
/* Allocate the arg list */
msg->sm_ArgList = (struct WBArg *)
AllocMem(sizeof(struct WBArg) * argc, MEMF_PUBLIC | MEMF_CLEAR);
if(!msg->sm_ArgList) {
FreeStartup(msg);
return 0;
}
/* Empty out all args, just in case this aborts, so cleanup
* can clean it up
*/
msg->sm_NumArgs = argc;
for(i = 0; i < argc; i++) {
msg->sm_ArgList[i].wa_Lock = 0;
msg->sm_ArgList[i].wa_Name = 0;
}
/* Get lock and name for wbargs */
for(i = 0; i < argc; i++) {
flock = Lock(argv[i]);
if(!flock) {
FreeStartup(msg);
return 0;
}
msg->sm_ArgList[i].wa_Lock = ParentDir(flock);
UnLock(flock);
if(!msg->sm_ArgList[i].wa_Lock) {
FreeStartup(msg);
return 0;
}
/* Get the tail end of the file name. I could also do an Examine
* on the lock, but didn't want to bother allocating a File Info
* Block that wouldn't fit under the tracking via the startup
* message.
*/
namep = argv[i];
for(s = argv[i]; *s; s++)
if(*s=='/' || *s==':')
namep = s+1;
msg->sm_ArgList[i].wa_Name =
(char *)AllocMem(strlen(namep)+1, MEMF_PUBLIC);
if(!msg->sm_ArgList[i].wa_Name) {
FreeStartup(msg);
return 0;
}
strcpy(msg->sm_ArgList[i].wa_Name, namep);
}
/* Create the process. It is now running, but will wait for the
* startup message.
*/
msg->sm_Process =
CreateProc(msg->sm_ArgList[0].wa_Name, pri, msg->sm_Segment, stack);
if(!msg->sm_Process) {
FreeStartup(msg);
return 0;
}
/* Initialise the message part of the startup message, and pass it to
* the process. At this point it will actually start ding work
*/
msg->sm_Message.mn_ReplyPort = rport;
msg->sm_Message.mn_Length = sizeof(struct WBStartup);
msg->sm_Message.mn_Node.ln_Type = NT_MESSAGE;
PutMsg(msg->sm_Process, msg);
/* return message. Not very useful, but it's as meaningful a response as
* any.
*/
return msg;
}
SHAR_EOF
# End of shell archive
exit 0
--
Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page
Have five nice days.